#pragma once

#include "Symbol/Symbol.hpp"
#include "Symbol/SymbolKind.hpp"
#include "Syntax/Object/TypeKind.hpp"
#include <memory>

class TypeSymbol;
typedef std::shared_ptr<TypeSymbol> SharedTypeSymbol;

class TypeSymbol : public Symbol
{
private:
    TypeKind thisType;

private:
    static SharedTypeSymbol Error;
    static SharedTypeSymbol Bool;
    static SharedTypeSymbol Int;
    static SharedTypeSymbol String;

public:
    static SharedTypeSymbol GetError()
    {
        if(Error == nullptr)
            Error = std::make_shared<TypeSymbol>("?", TypeKind::Error);
        return Error;
    }
    static SharedTypeSymbol GetBool()
    {
        if(Bool == nullptr)
            Bool = std::make_shared<TypeSymbol>("bool", TypeKind::Bool);
        return Bool;
    }
    static SharedTypeSymbol GetInt()
    {
        if(Int == nullptr)
            Int = std::make_shared<TypeSymbol>("int", TypeKind::Int);
        return Int;
    }
    static SharedTypeSymbol GetString()
    {
        if(String == nullptr)
            String = std::make_shared<TypeSymbol>("string", TypeKind::String);
        return String;
    }

    bool eq(const SharedTypeSymbol &other) { return this->thisType == other->thisType; }
    bool eq(const TypeSymbol &other) { return this->thisType == other.thisType; }

    bool operator==(TypeSymbol other) { return this->thisType == other.thisType; }

public:
    TypeSymbol(std::string name, TypeKind type) : Symbol(name, SymbolKind::Type), thisType(type) {}

    static SharedTypeSymbol Make(TypeKind type);
};